#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "model.h"

/* marche */

int pow(int x,int y){
    if(y>1)
        return (x*pow(x,y-1));
    else
    {
        if(y==1)
            return (x);
        else
            return 1;
    }
}

int readall(char *c){
	int r = 0;
	int i;
	for(i=0;c[i]!=0;++i)
		r+=pow(2,i)*c[i];
	return r;
}

int oct(char *c){
	int r = 0;
	int i;
    for(i=0;c[i]!=0;++i)
        r+=pow(100,i)*c[i];
    return r;
}

void writeall(char *c,int x,int size){
	int i;
	for (i=size; i>=0;i--){
		c[size-i] = (x / (pow(2,i)))mod(pow(2,i+2));
	}
}

void writeoct(char *c,int x,int size){
    int i;
    for (i=size; i>=0;i--){
        c[size-i] = (x / (pow(100,i)))mod(pow(100,i+2));
    }	
}

data bmp2data(char[] path){
	data ndata;
	char *tr = malloc (4);
	size_t bpp;
	size_t start;
	size_t cmp;
	char *sign;
	size_t s;
	size_t dib;
	ndata = malloc(sizeof(struct s_data));
	int fp = open(path,O_RDONLY);
	if(fp<0)
		perror("Can't open file");
	// Read "BM"on the header 
	fread(tr,1, 2,fp);
	// Check if the file is BM
	if (tr =="BM") then{
	// Read file size 
		fread(&s,4,1,fp);
	// Skip 4 bytes
		read(fp,tr,4);
	// Store start of data
		fread(&start, 4,1,fp);
	// Read header size
		fread(tr, 4,1,&dib);
	// BITMAPINFOHEADER (windows version 3.0+
		if(dib >= 40)
		{
			fread(ndata.w,4,1,fp);
			fread(ndata.h,4);
			ndata->h = readall(tr);
			read(fp,tr, 2);
			read(fp,tr,2);
			bpp = readall(tr);
			read(fp,tr,4)
			cmp = readall(tr);
			read(fp,tr,4)
			ndata->rw = readall(tr);
			read(fp,tr,4)
			ndata->rh = readall(tr);
			seek(lp, start,SEEK_SET);
			datb(ndata,fp,h,w);
		}
	}
	close(fp);
	free(tr);
	return ndata;
}

data gif2data(char[] path)
{
  data ndata;
  char *tr = malloc(4);
  int sign;
  size_t size;
  size_t size_color, pixelaspect, background_color, lzw;
  size_t x, i, y; 
  ndata = malloc(sizeof(struct s_data));
  int fp = open(path,O_RDONLY);
  if (fp<0)
    perror("Can't open gif file");
  //gif marquage Header Block 3 bits signature 3 bits version
  read(fp,tr,6);
  *sign = oct(tr);
  //logical width
  read(fp, tr, 2);
  //logical heigth
  size = readall(tr);
  //packetfield
  read(fp, tr,1);
  size_color = readall;
  read(fp, tr,1);
  background_color = readall(tr);(tr);
  read(fp, tr,1);
  pixelaspect= readall(tr);
  //global color table
  read(fp, tr, size_color);
  
  //BLocks
   //separator left right position
  read(fp, tr, 5);
  //image width Image heigth
  read(fp, tr, 2);
  ndata->w = readall(tr);
  
  read(fp, tr, 2);
  ndata->h = readall(tr);
  //Image Data local color table flag, interlace, sort
  read (fp, tr, 1);
  read (fp, tr, size_color);
  read (fp, tr, 1);
  lzw = readall(tr);
  read (fp, tr, 1);
  blocksize = readall (tr)
  data->array = malloc (w*h*sizeof(struct pixdat));
  for(x = 0; x < blocksize; x++)
    {
      for(i = h; i>=0;--i){
	for(y = 0; y<w;++j){
	  read(fp,tr,1);
	  ndata->array[i*h+j].r = readall(tr);
	  read(fp,tr,1);
	  ndata->array[i].g = readall(tr);
	  read(fp,tr,1);
	  ndata->array[i].b = readall(tr);
	  
	}
      }
    }
  free(tr);
  
  close (fp);
  return ndata;
}
void datb(data ndata,file fp,size_t h,size_t w, size_t bpp){
	size_t y,i,v;
	char *tr = malloc (5);
	ndata->array = malloc (w*h*sizeof(struct pixdat));
		for(i = h; i>=0;--i){
			for(y = 0; y<w;++j){
				read(fp,tr,1);
				ndata->array[i*h+j].b = readall(tr);
           		read(fp,tr,1);
				ndata->array[i].g = readall(tr);
        	    read(fp,tr,1);
				ndata->array[i].r = readall(tr);
				if(bpp = 32)
				{
					read(fp,tr,1);
					ndata->array[i].a = readall(tr);
				}
				else
					ndata->array[i].a = 0;
			}
			read(fp,tr,((4 - (y*3%4))%4));
		}
	free(tr);
}

void data2bmp(data bdata,char *name){
	int s = 0;
	int pos = 0;
	int i,j,m;
	int fi = open(name, O_CREAT | O_TRUNC | O|EXCL | O_NOCTTY | O_WRONLY,0666);
	char *buff = malloc(4);
	buff = "BM";
	write(fi, buff, 2);
	write(fi, buff, 4);
	buff = "BTBT";
	write(fi, buff, 4);
	writeall(buff, ftell(fi)+44,4);
	write(fi, buff, 4);
	writeall(buff,40,4);
	write(fi,buff,4);
	writeall(buff,bdata->w,4);
	write(fi,buff,4);
	writeall(buff,bdata->h,4);
	write(fi,buff,4);
	writeall(buff,1,2);
	write(fi,buff,2);
	writeall(buff,24,2);
	write(fi,buff,2);
	writeall(buff,0,4);
	write(fi,buff,4);
	pos = ftell(fi);
	write(fi,buff,4);
	writeall(buff,bdata->rh,4);
	write(fi,buff,4);
	writeall(buff,bdata->rh,4);
	write(fi,buff,4);
	writeall(buff,0,4);
	write(fi,buff,4);
	write(fi,buff,4);
	m = ((4-(bdata->w*3)%4)%4);
	for(i = (bdata->h)-1; i>=0;--i){
		for(j = 0; j<bdata->w;++j){
			writeall(buff,bdata->array[i*bdata->w + j].b,1)
			write(fi,buff,1);
                        writeall(buff,bdata->array[i*bdata->w + j].g,1)
                        write(fi,buff,1);
                        writeall(buff,bdata->array[i*bdata->w + j].r,1)
                        write(fi,buff,1);
			s+=3;
		}
		write(fi,buff,m);
		s +=m;
	}
	seek(fi, pos,SEEK_SET);
	writeall(buff,s,4);
	write(fi,buff,4);
	seek(fi,2,SEEK_SET);
	writeall(buff,s+54,4);
	write(fi,buff,4);
	free(buff);
	close(fi);
}


void data2gif(data bdata,char *name){
  size_t s = 0;
  size_t pos = 0;
  size_t i,j,m;
  int fi = open(name, O_CREAT | O_TRUNC | O|EXCL | O_NOCTTY | O_WRONLY,0666);
  if (fi < 0)
    perror("thug aim");
  char *buff = malloc(4);
  buff = "GIF87a"; //header
  write(fi, buff, 6);
  buff = bdata->w; //width
  write(fi, buff, 2);
  buff = bdata->h; //height
  write(fi, buff, 2);
  //packedfield
  buff = "FIXME size_color";
  write(fi, buff, 1);
  buff = "FIXME background_color";
  write(fi, buff, 1);
  buff = "FIXME pixel aspect";
  write(fi, buff,1);
  buff = "21F9040000000000"; //graphics control extension
  write(fi, buff; 9);
  buff = "2C000000"; //image separator
  write(fi,buff,5);
  buff = bdata->w; 
  write(fi,buff,2);
  buff = bdata->h; //width and height again
  write(fi,buff,2);
  buff = "00"; //packed field
  write(fi,buff,2);
  /* Image data              FIX ME */
}
